<template>
    <view class="table-container">
        <scroll-view scroll-x scroll-y class="th-table">
            <table class="analysis-table">
                <thead data-group class="sticky_top">
                    <!-- 头部 -->
                    <tr data-item class="left" v-for="(row, index) in  table.renderHeaderList " :key="index">
                        <th :class="['tdTitle', table.fixedLeftEvent(columnsItem)]" v-for="columnsItem in row "
                            :key="columnsItem.prop" :rowspan="table.computedHeaderRowSpan(columnsItem)"
                            :colspan="table.computedHeaderColSpan(columnsItem)"
                            :style="{ minWidth: columnsItem.width + 'rpx' }" :align="columnsItem.align || 'left'">
                            <block v-if="columnsItem.headerRender">
                                <slot :name="columnsItem.headerRender" :scope="{ column: columnsItem }">
                                </slot>
                            </block>
                            <view v-else> {{ columnsItem.label }}</view>

                            <!-- <headerCell :columnsItem="columnsItem"></headerCell> -->
                        </th>
                    </tr>
                </thead>
                <!-- <thead>
                <tr v-for="(row, index) in  table.renderHeaderList " :key="index">
                    <th v-for="columnsItem in row " :key="columnsItem.prop"
                        :rowspan="table.computedHeaderRowSpan(columnsItem)"
                        :colspan="table.computedHeaderColSpan(columnsItem)" :style="{ minWidth: columnsItem.width + 'rpx' }"
                        align="left">
                        {{ columnsItem.label }}
                    </th>
                </tr>
            </thead> -->
                <tbody data-group>
                    <tr data-item :class="['table-count', 'left', item.active ? 'row-active--high' : '']"
                        v-for="( item, index ) in  table.tableData" @click="table.getTableRow(item, index)">
                        <template v-for="( headerItem, headerIndex ) in   table.renderDataList " :key="headerIndex">
                            <td v-show="table.computedTdColspan(item, index, headerItem) !== 0 &&
                                table.computedTdRowspan(item, index, headerItem) !== 0"
                                :class="['cell-b', table.pendingEvent(item, index, headerItem), table.fixedLeftEvent(headerItem, item, index)]"
                                :style="table.styleEvent(item, index, headerItem)"
                                :colspan="table.computedTdColspan(item, index, headerItem)"
                                :rowspan="table.computedTdRowspan(item, index, headerItem)"
                                :align="headerItem.align || 'left'">
                                <view v-if="headerItem.slot" class="td-cell__pending">
                                    {{ table.renderSlot(item, index, headerItem) }}
                                </view>
                                <view v-else-if="headerItem.render">
                                    <slot :name="headerItem.render"
                                        :scope="{ row: item, rowIndex: index, column: headerItem, columnIndex: headerIndex }">
                                    </slot>
                                </view>
                                <view v-else class="td-cell__pending">{{ item[headerItem.prop] }}</view>
                                <!-- // 动态组件提前写好组件去渲染对应的组件，-->
                                <!-- <component :is="components[headerItem.type]"
                                :ref="(el: unknown) => setComponentRef(el, headerItem.prop)" :form-item="headerItem"
                                :value="item"></component> -->
                            </td>
                        </template>
                    </tr>
                </tbody>
                <!-- <tbody>
                <tr class="table-count" v-for="( item, index ) in  table.tableData ">
                    <template v-for="( headerItem, headerIndex ) in   table.renderDataList " :key="headerIndex">
                        <td v-show="table.computedTdColspan(item, index, headerItem) !== 0 &&
                            table.computedTdRowspan(item, index, headerItem) !== 0"
                            :class="['cell-b', table.pendingEvent(item, index, headerItem), table.fixedLeftEvent(headerItem, item, index)]"
                            :style="table.styleEvent(item, index, headerItem)"
                            :colspan="table.computedTdColspan(item, index, headerItem)"
                            :rowspan="table.computedTdRowspan(item, index, headerItem)" :align="headerItem.align || 'left'">
                            <span v-if="headerItem.slot" class="td-cell__pending">
                                {{ table.renderSlot(item, index, headerItem) }}
                            </view>
                            <view v-else class="td-cell__pending">{{ item[headerItem.prop] }}</view>
                        </td>
                    </template>
                </tr>
            </tbody> -->
            </table>
        </scroll-view>
    </view>
</template>

<script setup lang="ts">


const props = withDefaults(defineProps<{
    columns?: []
    tableData?: any[];
}>(), {
    columns: () => [],
    tableData: () => [],
})

const emit = defineEmits(['getRow'])

const table = reactive({
    headerIndex: null,
    renderHeaderList: [],
    tableData: [],
    renderDataList: [],
    btnOne: true,
    /**
    * @description 递归扁平化配置数组，得到渲染表头的数组以及横跨的的行数
    * @param columns children
    */
    handleRenderHeaderList: (columns: any[]) => {
        // 用于记录深度
        table.headerIndex += 1
        if (table.renderHeaderList.length <= table.headerIndex) {
            table.renderHeaderList.push(columns)
        } else {
            table.renderHeaderList[table.headerIndex] = [...table.renderHeaderList[table.headerIndex], ...columns]
        }
        // 用于记录是否重置深度
        let isClearIndex = true
        columns.forEach((item) => {
            // 判断是否还有子集
            if (item.children && item.children.length > 0) {
                isClearIndex = false
                table.handleRenderHeaderList(item.children)
            }
        });
        if (isClearIndex) {
            table.headerIndex = 0
        }
    },
    /**
     * @description 单独rowspan的计算
     * @param columnsItem 单元格的配置
     * @return 单元格的列数 
     */
    computedHeaderRowSpan: (columnsItem) => {
        if (!columnsItem.children) {
            return table.renderHeaderList.length
        }
        return 1
    },
    /**
     * @description 单独colSpan的计算
     * @param columnsItem 单元格的配置
     * @return 单元格的列数
     */
    computedHeaderColSpan: (columnsItem) => {
        if (!columnsItem.children) {
            return 1
        }
        return table.flatColumnsItemChildren(columnsItem.children).length
    },

    /** 
     * @description 深度遍历扁平化数组获取单元格所占的列数
     * @param columnsItem 单元格的配置
     * @return 返回扁平化后的数组
     */
    flatColumnsItemChildren: (columnsItem) => {
        // 深度遍历,扁平化数组
        let node, list = [...columnsItem], nodes = [];
        while (node = list.shift()) {
            // 要过滤一下没有prop的，没有prop的列不参与最终的宽度计算
            if (node.prop) {
                nodes.push(node)
            }
            node.children && list.unshift(...node.children)
        }
        return nodes
    },
    /** 
    * @description 深度遍历扁平化数组获取所有props参数列数
    * @return 返回扁平化后的数组
    */
    handleRenderDataList: () => {
        table.renderHeaderList.map(item => {
            item.map(item => {
                item.prop && table.renderDataList.push(item)
            })
        })
    },
    /**
    * @description 计算单元格rowspan的占位
    * @param item 单元格一行的值
    * @param index 索引
    * @param columns 当前的单元格配置
    * @return colspan
    */
    computedTdRowspan: (item: any, index: number, columns: any): number | undefined => {
        if (columns.customCell) {
            let rowspan: number | undefined = 1
            if (columns.customCell(item, index, columns).rowspan === 0) {
                rowspan = 0
            }
            if (columns.customCell(item, index, columns).rowspan) {
                rowspan = columns.customCell(item, index, columns).rowspan
            }
            return rowspan
        }
        // if (item.col != null) {
        //     return item.rowspan
        // }

        return 1;
    },
    /**
     * @description 计算单元格colspan的占位
     * @param item 单元格一行的值
     * @param index 索引
     * @param columns 当前的单元格配置
     * @return colspan
     */
    computedTdColspan: (item: any, index: number, columns: any): number | undefined => {
        if (columns.customCell) {
            let colspan: number | undefined = 1
            if (columns.customCell(item, index, columns).colspan === 0) {
                colspan = 0
            }
            if (columns.customCell(item, index, columns).colspan) {
                colspan = columns.customCell(item, index, columns).colspan
            }
            return colspan
        }
        return 1;
    },
    /**
     * @description 自定义单元格数据
     * @param item 单元格一行的值
     * @param index 索引
     * @param columns 当前的单元格配置
     * @return colspan
     */
    renderSlot: (item: any, index: number, columns: any) => {
        return columns.slot && columns.slot({ item, index, columns })
    },
    /**
   * @description 标记为删除行
   * @param item 单元格一行的值
   * @param index 索引
   * @param columns 当前的单元格配置
   * @return {string} tdClass
   */
    pendingEvent: (item: any, index: number, columns: any) => {
        if (!columns.slot && columns.label != '工序') {
            return item[columns.prop] && item.status == 4 ? 'td-cell' : ''
        }
        const res = table.renderSlot(item, index, columns)
        return res && columns.status == 4 ? 'td-cell' : ''
    },
    /**
    * @description 自定义样式
    * @param item 单元格一行的值
    * @param index 索引
    * @param columns 当前的单元格配置
    * @return {string} tdClass
    */
    styleEvent: (item: any, index: number, columns: any) => {
        let style = {}
        if (columns.customStyleCell) {
            if (columns.customStyleCell(item, index, columns)) {
                style = columns.customStyleCell(item, index, columns)
            }
        }
        return style
    },
    /**
     * 获取当前行
     */
    getTableRow: (item: any, index: number) => {
        table.tableData.forEach(item => item.active = false)
        if (table.tableData[index]) {
            table.tableData[index].active = true;
            emit('getRow', { row: item, rowIndex: index })
        }

    },

    fixedLeftEvent: (columns: any, item: any, index: number) => {
        if (columns.fixed && columns.fixed == 'left' && !table.btnOne) {
            // if (index === table.tableData.length - 1) {
            //     return ['sticky_left']
            // }
            return ['sticky_left', 'shadow_left']
        }
    },


})

const scrollView = () => {
    // 获取滚动容器
    var scrollContainer = document.getElementById('scroll-container');
    let myWidth = scrollContainer.scrollWidth - scrollContainer.clientWidth;
    //监听滚动
    scrollContainer.addEventListener("scroll", throttle(() => {
        let needWidth = myWidth - scrollContainer.scrollLeft;
        needWidth = Math.abs(needWidth); //允许误差在5px以内
        if (scrollContainer.scrollLeft >= myWidth || needWidth < 5) {
            //滚动到了右边
            table.btnOne = false;
        }
        if (scrollContainer.scrollLeft == 0) {
            //滚动到了左边
            table.btnOne = true;
        }
    }));
}


const reset = () => {
    table.headerIndex = null
    table.renderHeaderList = []
    table.tableData = []
    table.renderDataList = []
}


const render = () => {
    reset()

    table.handleRenderHeaderList(props.columns)

    table.handleRenderDataList()

    table.tableData = props.tableData
}

watch(
    () => props.tableData,
    (val) => {
        render()
    },
    {
        deep: true,
        immediate: true
    }
)

</script>

<style scoped lang="scss">
@import './table.scss';


:deep() {
    .td-cell {
        // display: inline-block;
        // width: 100%;
        position: relative;

        &::after {
            content: "";
            position: absolute;
            top: 50%;
            left: 0;
            width: 100%;
            height: 0;
            border-bottom: 1px solid #f56c6c;
            z-index: 1;
        }

        &.td-cell__pending {
            color: #f56c6c;
        }
    }

    .sticky_top {
        position: sticky;
        top: 0;
        z-index: 9;

        th::before {
            content: '';
            width: 100%;
            height: 1px;
            background: #dedede;
            position: absolute;
            top: -1px;
            left: 0;
        }
        th::after {
            content: '';
            width: 1px;
            height: 100%;
            background: #dedede;
            position: absolute;
            top: 0;
            right: -1px;
        }
    }


    .th-table {
        max-height: 500px;
    }
}
</style>